﻿#pragma once

#include "common.h"
#include "bind.h"
#include <map>

namespace anip
{
	namespace ui
	{
		class ResourceTable
		{
		private:
			std::map<string, wstring> _stringTable;
			std::map<string, color> _colorTable;
			std::map<string, float> _valTable;

			// used to anchor references for bindables returned
			// by getBinded<>
			bindable<bool> _signal = false;

		public:
			typedef std::pair<string, wstring> StringKey;
			typedef std::pair<string, color> ColorKey;
			typedef std::pair<string, float> ScalarKey;

			ResourceTable() {}
			ResourceTable(string file) {}

			template<typename T>
			T get(const string& k, const T& def);

			template<typename T>
			bindable<T> getBinded(const string& k, const T& def)
			{
				return bindable<T>(
					[=/* , *this */]() { return get<T>(k, def); },
					{ &_signal });
			}
		};

		extern ResourceTable currentTheme;

		namespace r
		{
			extern const bfloat CursorWidth; // default = 1
			extern const bfloat FontSize; // default = 16
			extern const bfloat ScrollSpeed; // default = 20
			extern const bfloat RoundRadius; // default = 2
			extern const bfloat DoubleClickThreshold; // default = 0.25

			extern const bfloat Scroller_Size; // default = 5

			extern const bfloat DockedWindow_HeaderFontSize; // default = 16
			extern const bfloat DockedWindow_HeaderSize; // default = 25
			extern const bfloat Window_HeaderFontSize; // default = 18
			extern const bfloat Window_HeaderSize; // default = 28
			extern const bfloat Window_ResizeZoneSize; // default = 7
			extern const bfloat Window_ControlBtn_Size; // default = 16
			extern const bfloat Window_ControlBtn_Distance; // default = 15
			extern const bfloat Window_Focused_ShadowSize; // default = 30
			extern const bfloat Window_Unfocused_ShadowSize; // default = 50

			extern const bfloat MenuBar_Margin; // default = 10

			extern const bfloat Menu_ShadowSize; // default = 10
			extern const bfloat Menu_xMargin; // default = 30
			extern const bfloat Menu_yMargin; // default = 5
			extern const bfloat Menu_RoundRadius; // default = 4
			extern const bfloat Menu_Check_OuterSize; // default = 12
			extern const bfloat Menu_Check_InnerSize; // default = 6
			extern const bfloat Menu_Check_RimSize; // default = 2
			extern const bfloat Menu_Label_FontSize; // default = 10

			extern const bfloat Button_PressFactor; // default = 0.7f
			extern const bfloat Button_HoverFactor; // default = 0.9f

			extern const bfloat Textfield_BorderWidth; // default = 2

			extern const bfloat ListViewItem_TextHeight; // default = 30

			extern const bfloat Autodock_DetachDistance; // default = 100

			extern const bfloat Flow_RowSpacing; // default = 15
			extern const bfloat Flow_LineSpacing; // default = 10
			extern const bfloat Flow_Separator; // default = 10
			extern const bfloat Flow_hMargin; // default = 10
			extern const bfloat Flow_vMargin; // default = 10

			extern const bfloat Flow_Text_hMargin; // default = 5
			extern const bfloat Flow_Text_vMargin; // default = 5
			extern const bfloat Flow_Button_MaxWidth; // default = 300
			extern const bfloat Flow_Slider_Width; // default = 100
			extern const bfloat Flow_Slider_MinHeight; // default = 20
			extern const bfloat Flow_Joystick_Size; // default = 100

			extern const bfloat SplitResizer_Width; // default = 5

			////

			extern const bcolor Scroller_Color; // default = {0.5f, 0.5f, 0.5f, 0.7f}

			extern const bcolor TextColor; // default = {0.0f, 0.0f, 0.0f, 1.0f}
			extern const bcolor CursorColor; // default = {0.0f, 0.0f, 0.0f, 1.0f}

			extern const bcolor Window_CloseButtonColor; // default = {0.9f, 0.4f, 0.3f, 1.0f}
			extern const bcolor Window_CaptionColor; // default = {1.0f, 1.0f, 1.0f, 1.0f}
			extern const bcolor Window_HeaderColor; // default = {0.4f, 0.4f, 0.4f, 1.0f}
			extern const bcolor Window_BackColor; // default = {0.9f, 0.9f, 0.9f, 1.0f}
			extern const bcolor Window_Focused_ShadowColor; // default = {0.0f, 0.0f, 0.0f, 0.6f}
			extern const bcolor Window_Unfocused_ShadowColor; // default = {0.0f, 0.0f, 0.0f, 0.5f}

			extern const bcolor Menubar_BackColor; // default = {0.97f, 0.97f, 0.97f, 1.0f}
			extern const bcolor Menu_ShadowColor; // default = {0.0f, 0.0f, 0.0f, 0.3f}
			extern const bcolor Menu_BackColor; // default = {0.95f, 0.95f, 0.95f, 0.85f}
			extern const bcolor Menu_LineColor; // default = {0.5f, 0.5f, 0.5f, 1.0f}
			extern const bcolor Menu_Separator_Color; // default = {0.7f, 0.7f, 0.7f, 1.0f}
			extern const bcolor MenuItem_HoverColor; // default = {0.7f, 0.9f, 1.0f, 1.0f}
			extern const bcolor MenuRadioBar_BackColor; // default = {0.95f, 0.95f, 0.95f, 1.0f}

			extern const bcolor Button_NormalColor; // default = {0.8f, 0.8f, 0.8f, 1.0f}
			extern const bcolor Button_SelectedColor; // default = {0.5f, 0.6f, 1.0f, 1.0f}

			extern const bcolor Textfield_BackColor; // default = {0.95f, 0.95f, 0.95f, 1.0f}
			extern const bcolor Textfield_BorderColor; // default = {0.7f, 0.7f, 0.7f, 1.0f}
			extern const bcolor Textfield_FocusedBorderColor; // default = {0.4f, 0.6f, 0.7f, 1.0f}

			extern const bcolor Slider_BackColor; // default = {0.7f, 0.7f, 0.7f, 1.0f}
			extern const bcolor Slider_ForeColor; // default = {0.4f, 0.5f, 1.0f, 1.0f}

			extern const bcolor Tabctrl_Header_NormalColor; // default = {0.8f, 0.8f, 0.8f, 1.0f}
			extern const bcolor Tabctrl_Header_SelectedColor; // default = {0.95f, 0.95f, 0.95f, 1.0f}
			extern const bcolor Tabctrl_Header_NormalTextColor; // default = {0.4f, 0.4f, 0.4f, 1.0f}
			extern const bcolor Tabctrl_Header_SelectedTextColor; // default = {0.0f, 0.0f, 0.0f, 1.0f}

			extern const bcolor DockContainer_HintColor; // default = {0.2f, 0.2f, 1.0f, 0.3f}
		}
		
		template<>
		inline wstring ResourceTable::get(const string& k, const wstring& def) 
		{
			if (_stringTable.count(k) == 0) return def;
			return _stringTable[k]; 
		}

		template<>
		inline color ResourceTable::get(const string& k, const color& def) 
		{
			if (_colorTable.count(k) == 0) return def;
			return _colorTable[k];
		}

		template<>
		inline float ResourceTable::get(const string& k, const float& def) 
		{
			if (_valTable.count(k) == 0) return def;
			return _valTable[k];
		}
	}
}